package com.seanchenxi.gwt.xmlrpc.client.model.impl;

import java.util.HashMap;
import java.util.Set;

import com.seanchenxi.gwt.xmlrpc.client.model.BaseModel;

/**
 * The Class BaseModelImpl.
 */
public class BaseModelImpl implements BaseModel {
	
	/**
	 * Generated Serial ID
	 */
	private static final long serialVersionUID = 972144037673726493L;
	
	/** The properties. */
	private HashMap<String, Object> properties;
	
	/**
	 * Instantiates a new base model impl.
	 */
	public BaseModelImpl(){
		this(new HashMap<String, Object>());
	}
	
	/**
	 * Instantiates a new base model impl.
	 *
	 * @param properties the properties
	 */
	public BaseModelImpl(HashMap<String, Object> properties){
		setProperties(properties);
	}
	
	/* (non-Javadoc)
	 * @see com.seanchenxi.gwt.xmlrpc.client.model.BaseModel#getProperties()
	 */
	@Override
	public HashMap<String, Object> getProperties() {
		return properties;
	}
	
	/* (non-Javadoc)
	 * @see com.seanchenxi.gwt.xmlrpc.client.model.BaseModel#getPropertyNames()
	 */
	@Override
	public Set<String> getPropertyNames(){
		return properties.keySet();
	}
	
	/* (non-Javadoc)
	 * @see com.seanchenxi.gwt.xmlrpc.client.model.BaseModel#get(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <X>X get(String property){
		return (X)properties.get(property);
	}
	
	/* (non-Javadoc)
	 * @see com.seanchenxi.gwt.xmlrpc.client.model.BaseModel#set(java.lang.String, java.lang.Object)
	 */
	@Override
	public <X> void set(String property, X value){
		properties.put(property, value);
	}
	
	/* (non-Javadoc)
	 * @see com.seanchenxi.gwt.xmlrpc.client.model.BaseModel#setProperties(java.util.Map)
	 */
	@Override
	public void setProperties(HashMap<String, Object> properties) {
		this.properties = properties;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((properties == null) ? 0 : properties.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		BaseModelImpl other = (BaseModelImpl) obj;
		if (properties == null) {
			if (other.properties != null)
				return false;
		} else if (!properties.equals(other.properties))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		StringBuilder model = new StringBuilder();
		String className = this.getClass().getName();
		className = className.substring(className.lastIndexOf(".")+1);
		model.append(className.replace("Impl", ""));
		model.append(" [ ");
		for(String key : getPropertyNames()){
			model.append(key);
			model.append("=");
			model.append(get(key).toString());
			model.append(", ");
		}
		model.deleteCharAt(model.lastIndexOf(","));
		model.append(" ] ");
		return model.toString();
	}
}
